package com.sec.android.app.myfiles.widget.tablet.bottomdetailview;

import android.content.Context;
import android.os.AsyncTask;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.sec.android.app.myfiles.R;
import com.sec.android.app.myfiles.fragment.AbsMyFilesFragment;
import com.sec.android.app.myfiles.info.MediaFile;
import com.sec.android.app.myfiles.module.abstraction.FileRecord;
import com.sec.android.app.myfiles.thumbnail.ThumbnailImageView;
import com.sec.android.app.myfiles.thumbnail.ThumbnailMgr;
import com.sec.android.app.myfiles.util.FileDetailUtils;
import com.sec.android.app.myfiles.util.SemFwWrapper;
import com.sec.android.app.myfiles.util.UiUtils;

import java.io.File;
import java.util.ArrayList;

/**
 * Created by jaebae on 2016-10-05.
 */
public class BottomDetailView {
    final Context mContext;
    ArrayList<FileRecord> mRecordList;
    AbsMyFilesFragment mFragment;
    TextView mFileName;
    TextView mFirstTop;
    private TextView mSecondTop;
    TextView mFirstBottom;
    private TextView mSecondBottom;
    ImageView mStorageIcon;
    private ImageView mFileTypeIcon;
    private ThumbnailImageView mThumbnail;
    private ImageView mThumbnailMiddle;
    private ImageView mThumbnailLast;
    private View mThumbnailLayout;
    private RelativeLayout mDetailLayout;
    private RelativeLayout mFileNameLayout;
    private AsyncTask<Void, Void, Void> mDetailInfoTask;

    BottomDetailView(View parent, Context context) {
        mContext = context;
        initView(parent);
    }

    public static BottomDetailView createView(View parent, Context context, BottomViewType viewType) {
        if (viewType == BottomViewType.BottomDetailView) {
            return new BottomDetailView(parent, context);
        } else if (viewType == BottomViewType.BottomDetailLeftFocusedView) {
            return new BottomDetailLeftFocusedView(parent, context);
        } else {
            return new BottomDetailBTView(parent, context);
        }
    }

    void initView(View parent) {
        mDetailLayout = (RelativeLayout) parent.findViewById(R.id.bottom_details);
        mFileNameLayout = (RelativeLayout) parent.findViewById(R.id.file_name_layout);
        mFileTypeIcon = (ImageView) parent.findViewById(R.id.file_type_icon);
        mStorageIcon = (ImageView) parent.findViewById(R.id.storage_icon);

        mFileName = (TextView) parent.findViewById(R.id.file_name);
        mFirstTop = (TextView) parent.findViewById(R.id.first_top);
        mFirstBottom = (TextView) parent.findViewById(R.id.first_bottom);
        mSecondTop = (TextView) parent.findViewById(R.id.second_top);
        mSecondBottom = (TextView) parent.findViewById(R.id.second_bottom);

        mThumbnailLast = (ImageView) parent.findViewById(R.id.thumbnail_last);
        mThumbnailMiddle = (ImageView) parent.findViewById(R.id.thumbnail_middle);
        mThumbnail = (ThumbnailImageView) parent.findViewById(R.id.thumbnail);
        mThumbnailLayout = parent.findViewById(R.id.thumbnail_layout);
    }

    public void updateView(ArrayList<FileRecord> recordList, AbsMyFilesFragment fragment) {
        mRecordList = new ArrayList<>(recordList);
        mFragment = fragment;

        int recordSize = mRecordList.size();
        switch (recordSize) {
            case 0:
                clearView();
                updateViewForNoRecord();
                break;
            case 1:
                clearView();
                updateViewForOneRecord();
                break;
            default:
                String firstTop = mFirstTop.getText().toString();
                String firstBottom = mFirstBottom.getText().toString();
                clearView();
                updateViewForSelectedRecords(firstTop, firstBottom);
                break;
        }
    }

    void clearView() {
        setViewInfo(mFileName, null);
        setViewInfo(mFirstTop, null);
        setViewInfo(mSecondTop, null);
        setViewInfo(mFirstBottom, null);
        setViewInfo(mSecondBottom, null);
    }

    void setVisibility(int visibility) {
        mDetailLayout.setVisibility(visibility);
        mFileNameLayout.setVisibility(visibility);
    }

    private void updateViewForNoRecord() {
        setViewInfo(mFileName, UiUtils.makeSelectedString(mContext, mRecordList.size()));
    }

    private void updateViewForOneRecord() {
        String name;
        if (mRecordList != null && !mRecordList.isEmpty()) {
            FileRecord rootRecord = mRecordList.get(0);
            if (rootRecord != null) {
                if (UiUtils.isInRTLMode(mContext)) {
                    name = "\u200F" + rootRecord.getName();
                } else {
                    name = "\u200E" + rootRecord.getName();
                }
                if (rootRecord.isDirectory()) {
                    setViewInfo(mFileName, name);
                    executeTask(mFirstTop, mFirstBottom, false);
                    setViewInfo(mFirstTop, getFormattedSizeString(0));
                    setViewInfo(mFirstBottom, getFormattedContainsString(0, 0));
                    setViewInfo(mSecondTop, getFormattedDateString(rootRecord));
                } else {
                    setViewInfo(mFileName, name);
                    setViewInfo(mFirstTop, getFormattedSizeString(calculateSize(rootRecord)));
                    String additionalInfo = getFormattedAdditionalInfoString(rootRecord);
                    if (additionalInfo != null) {
                        setViewInfo(mFirstBottom, getFormattedAdditionalInfoString(rootRecord));
                        setViewInfo(mSecondTop, getFormattedDateString(rootRecord));
                    } else {
                        setViewInfo(mFirstBottom, getFormattedDateString(rootRecord));
                    }
                }
            }
        }
    }

    private void updateViewForSelectedRecords(String prevTop, String prevBottom) {
        boolean onlyFiles = getSelectedRecordType();
        setViewInfo(mFileName, UiUtils.makeSelectedString(mContext, mRecordList.size()));
        setViewInfo(mFirstTop, prevTop);
        setViewInfo(mFirstBottom, onlyFiles ? null : prevBottom);
        executeTask(mFirstTop, mFirstBottom, onlyFiles);
    }

    private long calculateSize(FileRecord record) {
        long ret = 0;
        if (record != null) {
            if (record.getStorageType() == FileRecord.StorageType.Shortcut) {
                File file = SemFwWrapper.file(record.getFullPath());
                if (file.exists()) {
                    ret = file.length();
                }
            } else {
                ret = record.getSize();
            }
        }
        return ret;
    }

    private long calculateLastModifiedDate(FileRecord record) {
        long ret = 0;
        if (record != null) {
            if (record.getStorageType() == FileRecord.StorageType.Shortcut) {
                File file = SemFwWrapper.file(record.getFullPath());
                if (file.exists()) {
                    ret = file.lastModified();
                }
            } else {
                ret = record.getDate();
            }
        }
        return ret;
    }

    void setViewInfo(View view, String info) {
        if (info != null) {
            ((TextView) view).setText(info);
            view.setVisibility(View.VISIBLE);
        } else {
            view.setVisibility(View.GONE);
        }
    }

    public void cancelTask() {
        if (mDetailInfoTask != null && mDetailInfoTask.getStatus() != AsyncTask.Status.FINISHED) {
            mDetailInfoTask.cancel(true);
        }
    }

    protected boolean getSelectedRecordType() {
        boolean isOnlyFiles = true;
        for (FileRecord record : mRecordList) {
            if (record != null && record.isDirectory()) {
                isOnlyFiles = false;
                break;
            }
        }
        return isOnlyFiles;
    }

    protected void executeTask(final TextView sizeView, final TextView containView, final boolean isOnlyFiles) {
        cancelTask();
        mDetailInfoTask = new AsyncTask<Void, Void, Void>() {
            private FileDetailUtils.DirInfo mDirInfo;

            @Override
            protected Void doInBackground(Void... params) {
                mDirInfo = new FileDetailUtils.DirInfo();
                for (FileRecord record : mRecordList) {
                    FileDetailUtils.getDirInfo(mContext, record, mDirInfo, true);
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void aVoid) {
                if (!isCancelled()) {
                    setViewInfo(sizeView, (mDirInfo.size == 0 && mDirInfo.fileCnt == 0 && mDirInfo.dirCnt == 0) ? null : getFormattedSizeString(mDirInfo.size));
                    setViewInfo(containView, isOnlyFiles ? null : getFormattedContainsString(mDirInfo.fileCnt, mDirInfo.dirCnt));
                }
            }
        };
        mDetailInfoTask.execute();
    }

    protected void updateThumbnailView() {
        setThumbnailViewVisibility();
        setThumbnailView();
    }

    protected void setThumbnailViewVisibility() {
        int size = mRecordList.size();
        switch (size) {
            case 0:
                setThumbnailViewVisibility(View.VISIBLE, View.GONE, View.GONE, View.GONE, View.GONE);
                break;
            case 1:
                setThumbnailViewVisibility(View.GONE, View.GONE, View.VISIBLE, View.GONE, View.GONE);
                break;
            case 2:
                setThumbnailViewVisibility(View.GONE, View.GONE, View.VISIBLE, View.VISIBLE, View.GONE);
                break;
            default:    // more than 2
                setThumbnailViewVisibility(View.GONE, View.GONE, View.VISIBLE, View.VISIBLE, View.VISIBLE);
                break;
        }
    }

    protected void setThumbnailViewVisibility(int storageIconVisible, int fileTypeIconVisible, int thumbnailVisible, int thumbnailMiddleVisible, int thumbnailLastVisible) {
        mStorageIcon.setVisibility(storageIconVisible);
        mFileTypeIcon.setVisibility(fileTypeIconVisible);
        mThumbnail.setVisibility(thumbnailVisible);
        mThumbnailMiddle.setVisibility(thumbnailMiddleVisible);
        mThumbnailLast.setVisibility(thumbnailLastVisible);
    }

    protected void setThumbnailView() {
        if (mRecordList != null && !mRecordList.isEmpty()) {
            FileRecord rootRecord = mRecordList.get(0);
            if (rootRecord != null) {
                mThumbnail.setThumbnailView(mFragment, rootRecord, mThumbnailLayout);
                mThumbnail.setImageBitmap(null);
                ImageView view = ThumbnailMgr.getInstance(mContext).loadThumbnail(rootRecord, mThumbnail, mThumbnail);
                if (view == null) {
                    mFileTypeIcon.clearColorFilter();
                    mFileTypeIcon.setImageDrawable(MediaFile.getFileTypeDrawable(mContext, rootRecord));
                    mFileTypeIcon.setVisibility(View.VISIBLE);
                    if (mRecordList.size() > 1) {
                        mThumbnail.setBackgroundResource(R.color.bottom_detail_thumbnail_background_color);
                    }
                }
            }
        }
    }

    protected String getFormattedSizeString(long size) {
        return mContext.getString(R.string.size) + " : " + UiUtils.makeFileSizeString(mContext, size);
    }

    private String getFormattedContainsString(int fileCnt, int dirCnt) {
        String contains = "";
        if (mFragment.isSelectActionMode()) {
            contains += mContext.getString(R.string.contains) + " : ";
        }
        contains += UiUtils.makeContainsString(mContext, fileCnt, dirCnt);
        return contains;
    }

    private String getFormattedDateString(FileRecord record) {
        return mContext.getString(R.string.last_modified_time) + " : " + UiUtils.makeTimeString(mContext, calculateLastModifiedDate(record));
    }

    private String getFormattedAdditionalInfoString(FileRecord record) {
        String contentInfo = null;
        if (record.isAudioFileType() || record.isVideoFileType()) {
            long duration = FileDetailUtils.getMediaDuration(record);
            if (duration != 0) {
                contentInfo = mContext.getString(R.string.duration) + " : " + UiUtils.makeDurationString(duration);
            }
        } else if (record.isImageFileType()) {
            String resolution = UiUtils.makeResolutionString(mContext, FileDetailUtils.getImageResolution(record));
            if (resolution != null) {
                contentInfo = mContext.getString(R.string.resolution) + " : " + resolution;
            }
        }
        return contentInfo;
    }

    public enum BottomViewType {
        BottomDetailView,
        BottomDetailLeftFocusedView,
        BottomDetailBTView
    }

    public void refreshChildView() {
        setTextSize(mFileName, R.dimen.bottom_detail_file_name_text_size);
        setTextSize(mFirstTop, R.dimen.bottom_detail_text_size);
        setTextSize(mFirstBottom, R.dimen.bottom_detail_text_size);
        setTextSize(mSecondTop, R.dimen.bottom_detail_text_size);
        setTextSize(mSecondBottom, R.dimen.bottom_detail_text_size);

        setLayoutParams(mThumbnail, R.dimen.bottom_detail_thumbnail_size);
        setLayoutParams(mThumbnailMiddle, R.dimen.bottom_detail_thumbnail_size);
        setLayoutParams(mThumbnailLast, R.dimen.bottom_detail_thumbnail_size);
        setLayoutParams(mStorageIcon, R.dimen.bottom_detail_thumbnail_size);
        setLayoutParams(mFileTypeIcon, R.dimen.bottom_detail_file_type_icon_size);
    }

    protected void setTextSize(TextView view, int resId) {
        if (view != null) {
            float textSize = mContext.getResources().getDimensionPixelSize(resId);
            view.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
        }
    }

    private void setLayoutParams(View view, int resId) {
        setLayoutParams(view, resId, resId);
    }

    protected void setLayoutParams(View view, int resWidthId, int resHeightId) {
        if (view != null) {
            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
            layoutParams.width = mContext.getResources().getDimensionPixelSize(resWidthId);
            layoutParams.height = mContext.getResources().getDimensionPixelSize(resHeightId);
            view.setLayoutParams(layoutParams);
        }
    }
}
